﻿using System.ComponentModel;
using System.Reflection;
using SelfMadeMillionaire.Core.Entities;
using SelfMadeMillionaire.Core.Enums;
using SelfMadeMillionaire.Web.Infrastructure.Formatters;
using System;
using System.Web.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;


namespace SelfMadeMillionaire.Web.Infrastructure.Controllers
{
	public abstract class BaseController : Controller
	{
        protected void ClearProductTypeInSession()
        {
            Session[Constants.PRODUCT_TYPE_SESSION_KEY] = null;
        }

        public bool IsUsIP()
        {
            try
            {
                var ip = Request.UserHostAddress.Split('.');
                long ipNumeric = (ip.Length == 4) ? (int.Parse(ip[3]) + int.Parse(ip[2]) * 256 + int.Parse(ip[1]) * 256 * 256 + int.Parse(ip[0]) * 256 * 256 * 256) : 0;

                using (var conn = new SqlConnection(WebConfigurationManager.ConnectionStrings["DataContext"].ConnectionString))
                {
                    conn.Open();
                    try
                    {
                        var cmd = new SqlCommand(string.Format("select 1 from IpToCountry where Country = 'USA' and ({0} between FromIP and ToIP)", ipNumeric), conn);
                        var dt = new DataTable();
                        new SqlDataAdapter(cmd).Fill(dt);

                        return dt.Rows.Count > 0;
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
            }
            catch
            {
                return true;
            }
        }

        public void LogHit(string connect,
            string referrer,
            string script_name,
            string client_ip,
            string browser,
            string query)
        {
            using (var conn = new SqlConnection(connect))
            {
                conn.Open();
                try
                {
                    var cmd = new SqlCommand("spSaveHit", conn);
                    cmd.CommandType = CommandType.StoredProcedure;

                    cmd.Parameters.AddWithValue("@referrer", referrer);
                    cmd.Parameters.AddWithValue("@script_name", script_name);
                    cmd.Parameters.AddWithValue("@client_ip", client_ip);
                    cmd.Parameters.AddWithValue("@browser", browser);
                    cmd.Parameters.AddWithValue("@query", query);
                    cmd.ExecuteNonQuery();
                }
                finally
                {
                    conn.Close();
                }
            }
        }

		protected SelectList GetProductTypes(ProductType? selectedValue = null)
		{
			var list = new List<SelectListItem>();
			list.Add(new SelectListItem { Text = "Select..." });
			list.Add(new SelectListItem { Text = ProductTypeFormatter.GetProductTypeName(ProductType.SelfMadeMillionaire), Value = ((byte)ProductType.SelfMadeMillionaire).ToString(), });
			list.Add(new SelectListItem { Text = ProductTypeFormatter.GetProductTypeName(ProductType.MaggiesMoneyMountain), Value = ((byte)ProductType.MaggiesMoneyMountain).ToString(), });
            list.Add(new SelectListItem { Text = ProductTypeFormatter.GetProductTypeName(ProductType.BeginnersPortfolioOptions101), Value = ((byte)ProductType.BeginnersPortfolioOptions101).ToString(), });

            return new SelectList(list, "Value", "Text", selectedValue.HasValue ? (byte)selectedValue : (byte?)null);
		}

		protected SelectList GetIssueTypes(IEnumerable<IssueType> issueTypes, string selectedValue = null)
		{
			var list = new List<SelectListItem>();
			list.Add(new SelectListItem { Text = "Select..." });
			list.AddRange(issueTypes.Select(x => new SelectListItem { Text = x.Title, Value = x.ID.ToString() }));

			return new SelectList(list, "Value", "Text", selectedValue);
		}

		protected ProductType? GetProductTypeDepenenOnReferrer(ProductType? selectedProduct)
		{
			ProductType? productType = selectedProduct;

			if (Request.UrlReferrer != null)
			{
				if (Request.UrlReferrer.AbsoluteUri.Contains("MaggiesMoneyMountain"))
					productType = ProductType.MaggiesMoneyMountain;
			}

			return productType;
		}

		protected ProductType GetProductType(bool isSMM, bool isMMM)
		{
			if (isSMM && isMMM)
				return ProductType.SelfAndMaggies;
			else if (isMMM)
				return ProductType.MaggiesMoneyMountain;
			else if (isSMM)
				return ProductType.SelfMadeMillionaire;

			return ProductType.None;
		}

        protected ProductType? GetProductType()
        {
            //return (Request.Url.AbsoluteUri.Contains("MaggiesMoneyMountain")) ? ProductType.MaggiesMoneyMountain : ProductType.SelfMadeMillionaire;
            return Session[Constants.PRODUCT_TYPE_SESSION_KEY] == null ? (ProductType?)null : (ProductType)Enum.Parse(typeof(ProductType), Session[Constants.PRODUCT_TYPE_SESSION_KEY].ToString());
        }

		protected SelectList GetAccessLevels(object selectedValue = null)
		{
			return GetSelectListFromEnum<SubscriptionType>(false, selectedValue);
		}

        protected SelectList GetAccessLevelsFilter(object selectedValue = null)
        {
            return GetSelectListFromEnum<SubscriptionType>(true, selectedValue);
        }
        
		protected void Authenticate(string login, string firstName, string lastName, DateTime expireDate, string role, bool remember)
		{
            FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, login, DateTime.Now, DateTime.Now.AddYears(1), remember, string.Format("{0}|{1};{2}", role, firstName, lastName));
			string encTicket = FormsAuthentication.Encrypt(authTicket);
			HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
			
			if(remember)
				faCookie.Expires = authTicket.Expiration;
			
			Response.Cookies.Add(faCookie);
		}

        protected void ReAuthenticate(string oldLogin, string newLogin, string newFirstName, string newLastName)
        {
            //HttpCookie cookie = FormsAuthentication.GetAuthCookie(oldLogin, true);
            HttpCookie cookie = Request.Cookies[FormsAuthentication.FormsCookieName];
            FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);

            string ticketUserData = ticket.UserData.Substring(0, ticket.UserData.IndexOf('|') + 1);
            ticketUserData += string.Format("{0};{1}", newFirstName, newLastName);

            FormsAuthenticationTicket newticket = new FormsAuthenticationTicket(ticket.Version,
                                                              newLogin,
                                                              ticket.IssueDate,
                                                              ticket.Expiration,
                                                              true,
                                                              ticketUserData,
                                                              ticket.CookiePath);
            cookie.Value = FormsAuthentication.Encrypt(newticket);
            Response.Cookies.Set(cookie);
        }


		private SelectList GetSelectListFromEnum<T>(bool showSelectOption, object selectedValue = null) where T : struct, IConvertible
		{
			if (!typeof(T).IsEnum)
				throw new ApplicationException("T must be an enumerated type");

			var retList = new List<SelectListItem>();
			if (showSelectOption)
                retList.Add(new SelectListItem { Text = "Select...", Selected = (selectedValue == null) });

			var values = from T e in Enum.GetValues(typeof(T))
                         select new SelectListItem() { Text = e.ToString(), Value = Convert.ToByte(e).ToString(), Selected = Convert.ToByte(e) == (selectedValue == null?-1:Convert.ToByte(selectedValue)) };

			retList.AddRange(values);
            SelectListItem selectedItem = retList.SingleOrDefault(i => i.Selected);
            var list = new SelectList(retList, "Value", "Text", selectedItem == null?null:selectedItem.Value);

            return list;
		}

        public static string GetEnumDescription(Enum value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());

            DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute),false);

            if (attributes != null && attributes.Length > 0)
            {
                return attributes[0].Description;
            }
            else
            {
                return value.ToString();
            }
                
        }

        protected double CalculateNewPrice(double price, int discount, bool isPercent)
        {
            var newPrice = price;
            if (discount == 0)
            {
                return newPrice;
            }
            if (isPercent)
            {
                newPrice = price - (price * discount / 100);
            }
            else
            {
                newPrice = price - discount;
            }
            return newPrice;
        }

        protected UserRole GetUserRole(Subscriber subscriber)
        {
            var userRole = UserRole.None;

            if (subscriber.ProductType == (byte)(ProductType.SelfMadeMillionaire) || (subscriber.ProductType == (byte)(ProductType.SelfMadeMillionaire | ProductType.MaggiesMoneyMountain)))
            {
                if (subscriber.SubscriptionLevel != null)
                    switch ((SubscriptionType)subscriber.SubscriptionLevel)
                    {
                        case SubscriptionType.Free:
                            userRole = UserRole.SMMFree;
                            break;
                        case SubscriptionType.Silver:
                            userRole = UserRole.SMMSilver;
                            break;
                        case SubscriptionType.Gold:
                            userRole = UserRole.SMMGold;
                            break;
                    }
            }

            if (subscriber.ProductType == (byte)ProductType.MaggiesMoneyMountain || (subscriber.ProductType == (byte)(ProductType.SelfMadeMillionaire | ProductType.MaggiesMoneyMountain)))
                userRole = userRole | UserRole.MMM;

            return userRole;
        }		

	}
}
